package common

import (
	"crypto/md5"
	"fmt"
	"io"
	"math/rand"
	"strconv"
	"strings"
	"time"
)

// GetRandomIndex 根据随机概率返回对应的下标。
// rateNum: 概率总和，data: 各个概率值的数组。
// 返回值：下标和是否成功找到。
func GetRandomIndex(rateNum int, data []int32) (int, bool) {
	//随机一个数
	randNum := rand.Intn(rateNum) + 1
	var tempSum int
	for index, value := range data {
		tempSum += int(value)
		if tempSum > randNum {
			return index, true
		}
	}
	return 0, false
}

// Abs 返回整数的绝对值。
func Abs(n int32) int32 {
	if n >= 0 {
		return n
	}
	return -n
}

// Float32Abs 返回浮点数的绝对值。
func Float32Abs(f float32) float32 {
	if f >= 0 {
		return f
	}
	return -f
}

// Rand 在指定范围 [x, y] 内生成一个随机整数。
func Rand(x, y int32) int {
	return rand.Intn(int(Abs(y-x))+1) + int(x)
}

// CreateToken 根据当前时间和 ID 生成一个唯一的 MD5 token。
func CreateToken(curtime int64, id uint64) string {
	h := md5.New()
	_, _ = io.WriteString(h, strconv.FormatInt(curtime, 10))
	_, _ = io.WriteString(h, strconv.FormatUint(id, 10))
	token := fmt.Sprintf("%x", h.Sum(nil))
	return token
}

// AddrConvertToIpAndPort 将地址字符串转换为 IP 和端口。
// addr: 地址字符串，格式为 "IP:Port"。
// 返回值：IP、端口和错误信息。
func AddrConvertToIpAndPort(addr string) (string, int32, error) {
	b := strings.Split(addr, ":")
	ip := b[0]
	port, err := strconv.ParseInt(b[1], 10, 32)
	if err != nil {
		return "", 0, err
	}
	return ip, int32(port), nil
}

// SafeDelIU32 安全地从 v1 中减去 v2，确保结果不小于 0。
func SafeDelIU32(v1, v2 uint32) uint32 {
	if v1 <= v2 {
		return 0
	}

	return v1 - v2
}

// MaxI32 返回两个 int32 值中的较大值。
func MaxI32(v1, v2 int32) int32 {
	if v1 < v2 {
		return v2
	}

	return v1
}

// MaxI64 返回两个 int64 值中的较大值。
func MaxI64(v1, v2 int64) int64 {
	if v1 < v2 {
		return v2
	}

	return v1
}

// MinI32 返回两个 int32 值中的较小值。
func MinI32(v1, v2 int32) int32 {
	if v1 < v2 {
		return v1
	}

	return v2
}

// MinI64 返回两个 int64 值中的较小值。
func MinI64(v1, v2 int64) int64 {
	if v1 < v2 {
		return v1
	}

	return v2
}

// GetTimeMillisecond 将纳秒时间转换为毫秒时间。
func GetTimeMillisecond(v int64) int64 {
	return v / int64(time.Millisecond)
}

// GetCurrTimeMillisecond 获取当前时间的毫秒时间戳。
func GetCurrTimeMillisecond() int64 {
	return time.Now().UnixNano() / int64(time.Millisecond)
}

// GetTimeMillisecondT 获取指定时间的毫秒时间戳。
func GetTimeMillisecondT(t time.Time) int64 {
	return t.UnixNano() / int64(time.Millisecond)
}

// GetTimeSecondT 获取指定时间的秒级时间戳。
func GetTimeSecondT(t time.Time) int64 {
	return t.UnixNano() / int64(time.Second)
}
